﻿using System;
using System.Windows.Forms;
using System.Collections;
using IView;
using Presenter;
using DataTransferObject;
using System.Threading;
using System.Collections.Generic;
using System.IO;
using OutLook = Microsoft.Office.Interop.Outlook;
using Calendar;

using JSKE.DiaryAndTracking;

using DDay.iCal;
using DDay.iCal.Components;
using DDay.iCal.DataTypes;
using DDay.iCal.Serialization;
using System.Drawing;


namespace JSKE
{
    /*
     * Class quan trọng
     * Chức năng: 1. cung cấp cho người dùng nhập task, calendar
     *            2. Hiển thị kết quả trả về
     * Class này hiện thực các methods, properties trong interface IMainForm
     */
    /// <summary>
    /// 
    /// </summary>
    public partial class MainForm : FormLang, IMainForm
    {
        #region Attributes
        private PresenterMainForm presenter;
        private String pathToSaveJCalEvent = Application.StartupPath + @"\JSKEJCalendarEvent.xml";
        private BindingSource _bindingSource;
        static public OutLook.MAPIFolder OUTLOOK_FOLDER_CAL;
        static public OutLook._Application _outlookObj;
        public List<Event> eventsResult;
        private List<Task> taskList = new List<Task>();

        private Task currTask = new Task();

        private SystemConfiguration sysConfig;
        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="MainForm"/> class.
        /// </summary>
        public MainForm()
        {
            //InitializeComponent();
            // Khởi tạo presenter
            

            presenter = new PresenterMainForm(this, DATA_MODE);
            btnInsert.Enabled = true;
            
        }

        /// <summary>
        /// Handles the Load event of the MainForm control. Binding all task to GridView
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            GetLangAvailable();

            _bindingSource = new BindingSource();
            
            taskList = presenter.GetAllTasks();
            _bindingSource.DataSource = taskList;

            sysConfig = presenter.getSystemconfig();

            BindListViewTask(taskList, sysConfig);

            _outlookObj = new OutLook.Application();
            //Lấy thư mục default
            OUTLOOK_FOLDER_CAL = (OutLook.MAPIFolder)_outlookObj.Session.GetDefaultFolder(OutLook.OlDefaultFolders.olFolderCalendar);

            InitUpdateTaskData();
        }

        private void InitUpdateTaskData()
        {
            cbbExternalConstraint.Items.Clear();
            cbbExternalConstraint.Items.Add(PresenterMainForm.ExternalConstraints.NO_CONSTRAINT);
            cbbExternalConstraint.Items.Add(PresenterMainForm.ExternalConstraints.FINISH_ON_OR_BEFORE);
            cbbProjectName.DataSource = null;
            cbbProjectName.DataSource = sysConfig.TabProjectData.ListProjectName;
            cbbWHName.Items.Clear();
            for (int i = 0; i < sysConfig.TabWorkingHoursData.ListOfWorkingHourItems.Count; i++)
            {
                cbbWHName.Items.Add(sysConfig.TabWorkingHoursData.ListOfWorkingHourItems[i].WorkingHourName);                
            }
            if (cbbPriority.Items.Count > 0)
            {
                cbbPriority.SelectedIndex = 0;
            }
            if(cbbProjectName.Items.Count > 0)
                cbbProjectName.SelectedIndex = 0;
            if(cbbWHName.Items.Count > 0)
                cbbWHName.SelectedIndex = 0;
            if(cbbTaskStatus.Items.Count > 0)
                cbbTaskStatus.SelectedIndex = 1;
            dtpkDeadline.Enabled = false;
        }

        private void refreshTaskListData()
        {
            taskList = presenter.GetAllTasks();
            sysConfig = presenter.getSystemconfig();
            BindListViewTask(taskList, sysConfig);
            InitUpdateTaskData();
        }

        #endregion

        #region Even handlers for Controls

        private void btnAddTask_Click(object sender, EventArgs e)
        {
            TaskForm currentTaskForm = new TaskForm();
            currentTaskForm.ShowDialog(this);
            //_bindingSource.ResetBindings(true);
            refreshTaskListData();
        }

        private void groupboxEnable(Boolean enb)
        {
            groupBox1.Enabled = groupBox2.Enabled = groupBox3.Enabled = groupBox4.Enabled = enb;
            progressBar1.Enabled = true;
        }

        private void updateProgressBar(int val)
        {
            progressBar1.Refresh();
            progressBar1.Value = val;
            int percent = (int)(((double)progressBar1.Value / (double)progressBar1.Maximum) * 100);
            progressBar1.CreateGraphics().DrawString(percent.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Bold), Brushes.Blue, new PointF(progressBar1.Width / 2 - 10, progressBar1.Height / 2 - 7));
            
        }
        private void btnSchedule_Click(object sender, EventArgs e)
        {
            progressBar1.Visible = true;

            progressBar1.Refresh();

            updateProgressBar(6);
            
            Application.DoEvents();
            this.Cursor = Cursors.WaitCursor;
            groupboxEnable(false);
            presenter.UpdateOutlookAppointmentCalendar();

            updateProgressBar(12);

            scheduleThread();
            progressBar1.Value = 0;
            updateProgressBar(0);
            this.Cursor = Cursors.Default;
            //progressBar1.Visible = false;
            //groupBox2.Enabled = btnSchedule.Enabled = btnOption.Enabled = true;
            groupboxEnable(true);

            refreshTaskListData();
        }


        private void btnOption_Click(object sender, EventArgs e)
        {
            OptionForm optionForm = new OptionForm();
            optionForm.ShowDialog();
            refreshTaskListData();
        }

        private void btnDeleteTask_Click(object sender, EventArgs e)
        {
            if (_bindingSource.Count != 0)
            {
                DialogResult dlgRes = MessageBox.Show("Are you sure to delete selected tasks?", "Delete Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dlgRes == DialogResult.Yes)
                {
                    List<Task> delTaskList = new List<Task>();
                    this.currSelectedIndex -= listViewTask.SelectedIndices.Count;
                    for (int i = 0; i < listViewTask.SelectedIndices.Count; i++)
                    {
                        delTaskList.Add(taskList[listViewTask.SelectedIndices[i]]);
                    }
                    presenter.deleteTaskList(delTaskList);
                    refreshTaskListData();
                }
            }
            else
            {
                MessageBox.Show("There are no Tasks to be deleted!\nPlease input Tasks and try again.", "Important Note", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            //RollBack();
            this.Close();
        }

        private void btnImportTaskFromOutlook_Click(object sender, EventArgs e)
        {
            TaskFunctionalForm.TaskManagerForm taskManagerForm = new TaskFunctionalForm.TaskManagerForm();
            taskManagerForm.ShowDialog();
            _bindingSource.ResetBindings(true);
            refreshTaskListData();
        }
        #endregion

        #region IMainForm Members

        public void ShowMessageBox(string message)
        {
            MessageBox.Show(message);
        }

        public String GetPathToSaveConfig()
        {
            return Application.StartupPath + @"\JSKEData.bin";
        }

        public String GetPathToSaveTaskList()
        {
            return Application.StartupPath + @"\JSKETaskList.xml";
        }

        /// <summary>
        /// Thiết lập folder của outlook mà tại đó chương trình sẽ lấy ra các FreeTimeBlock. Path sẽ có dạng như sau:
        /// \\Personal Calendars\xxx\...\xxx
        /// </summary>
        /// <param name="path">The path.</param>
        public void SetOutlookAppointmentCalendar(string path)
        {
            if (path.Trim() != "")
            {
                string relativePath = path.Substring(2); // lọai bỏ 2 slashes đầu tiên
                string[] folders = relativePath.Split(new char[] { '\\' });
                OutLook._Application olts = new OutLook.Application();
                OutLook._NameSpace olNamespace = olts.GetNamespace("MAPI");
                OutLook.MAPIFolder oCurrentFolder = olNamespace.Folders[1]; // Root Folder là: Personal Calendars
                foreach (OutLook.MAPIFolder mm in olNamespace.Folders)
                {
                    if(mm.Name.Equals("Personal Folders"))
                    {
                        oCurrentFolder = mm;
                        break;
                    }
                }
                for (int i = 1; i < folders.Length; i++)
                {
                    oCurrentFolder = oCurrentFolder.Folders[folders[i]];
                }
                OUTLOOK_FOLDER_CAL = oCurrentFolder;
                
            }
        }
        #endregion


        //bool bFinish;

        #region xu ly doc/xuat/rollback appointment trong Outlook 2007

        /// <summary>
        /// Trả về list các freetimeBlock sau khi đọc list các appointment từ outlook. Chưa xử lí recurring appointment
        /// </summary>
        /// <returns></returns>
        public FreeTimeList FreeTimeListFromOutlook()
        {
            List<Event> events = new List<Event>();
            iCalendar iCal = new iCalendar();

            // test - ghi các appointment ra file
            /*using (StreamWriter writer = new StreamWriter("out.txt"))
            {
                foreach (Microsoft.Office.Interop.Outlook._AppointmentItem ApptItem in OUTLOOK_FOLDER_CAL.Items)
                {
                    writer.Write(ApptItem.Subject + ": \t\t" + ApptItem.Start + " ---" + ApptItem.End + "\t");
                    if (ApptItem.IsRecurring)
                    {
                        writer.Write("Recurring\t");
                    }
                    if (ApptItem.AllDayEvent)
                    {
                        writer.Write("Allday event\t");
                    }
                    writer.WriteLine();
                }
                writer.Close();
            }*/
            // end test
            DateTime startScheduleDate = this.presenter.GetStartScheduleDate();
            List<Microsoft.Office.Interop.Outlook._AppointmentItem> appoinmentsAfterStartSchedule = new List<OutLook._AppointmentItem>();
            foreach (Microsoft.Office.Interop.Outlook._AppointmentItem ApptItem in OUTLOOK_FOLDER_CAL.Items)
            {

                if (ApptItem.End.CompareTo(startScheduleDate) > 0 || ApptItem.IsRecurring)
                {
                    appoinmentsAfterStartSchedule.Add(ApptItem);
                }
            }
            //Duyệt qua tất cả các appointment và đưa vào list các events
            foreach (Microsoft.Office.Interop.Outlook._AppointmentItem ApptItem in OUTLOOK_FOLDER_CAL.Items)
            {

                //Trường hợp recurrence Appointment
                string name = ApptItem.Subject;
                if (ApptItem.IsRecurring)
                {
                    if (ApptItem.GetRecurrencePattern().RecurrenceType == OutLook.OlRecurrenceType.olRecursMonthly)
                    {
                        List<Event> evts = new List<Event>();
                        evts = MonthlyRecurrence(ApptItem);
                        foreach (Event e in evts)
                        {
                            events.Add(e);
                        }
                    }
                    if (ApptItem.GetRecurrencePattern().RecurrenceType == OutLook.OlRecurrenceType.olRecursWeekly)
                    {
                        List<Event> evts = new List<Event>();
                        evts = WeeklyRecurrence(ApptItem);
                        foreach (Event e in evts)
                        {
                            events.Add(e);
                        }
                    }
                    if (ApptItem.GetRecurrencePattern().RecurrenceType == OutLook.OlRecurrenceType.olRecursDaily)
                    {
                        List<Event> evts = new List<Event>();
                        evts = DailyRecurrence(ApptItem);
                        foreach (Event e in evts)
                        {
                            events.Add(e);
                        }
                    }
                }
                else if (ApptItem.AllDayEvent)
                {

                }
                // Appointment thông thường
                else
                {
                    Event evt = iCal.Create<Event>();
                    evt.Start = ApptItem.Start;
                    evt.End = ApptItem.End;
                    events.Add(evt);
                }
            }



            //sort event by start time
            events.Sort(delegate(Event evt1, Event evt2)
            {
                return evt1.Start.Local.CompareTo(evt2.Start.Local);
            });

            //nới rộng event theo time allowances
            int timeAllowancesBeforeEvents = 0;
            int timeAllowancesAfterEvents = 0;
            if (presenter.getSystemconfig().TabCalendarData.BeforeDefaultAllowces != "")
            {
                timeAllowancesBeforeEvents = int.Parse(presenter.getSystemconfig().TabCalendarData.BeforeDefaultAllowces);
            }
            if (presenter.getSystemconfig().TabCalendarData.AfterDefaultAllowces != "")
            {
                timeAllowancesAfterEvents = int.Parse(presenter.getSystemconfig().TabCalendarData.AfterDefaultAllowces);
            }
            for (int i = 0; i < events.Count; i++)
            {
                events[i].Start = events[i].Start.AddMinutes(-timeAllowancesBeforeEvents);
                events[i].End = events[i].End.AddMinutes(timeAllowancesAfterEvents);
            }
            ////////////////////////////////////

            //get freetimeblock
            FreeTimeList freeTimeList = new FreeTimeList();
            int id = 0;

            int index = 0;

            for (int i = 0; i < events.Count; i++)
            {
                if (events[i].Start.Local > DateTime.Now)
                {
                    index = i + 1;
                    freeTimeList.addFreeTimeBlockToList(new FreeTimeBlock((id++).ToString(),
                                                          DateTime.Now,
                                                          events[i].Start.Local)
                                      );
                    break;
                }
                else if (events[i].Start.Local < DateTime.Now && events[i].End.Local > DateTime.Now)
                {
                    index = i + 2;
                    if (events.Count - 1 > i && events[i + 1].Start.Local > events[i].End.Local)
                        freeTimeList.addFreeTimeBlockToList(new FreeTimeBlock((id++).ToString(),
                                                          events[i].End.Local,
                                                          events[i + 1].Start.Local)
                                      );
                    break;
                }
            }

            if (index == 0)
            {
                freeTimeList.addFreeTimeBlockToList(new FreeTimeBlock((id++).ToString(),
                                                          DateTime.Now,
                                                          DateTime.Now.AddDays(365))
                                      );
            }
            else
            {
                for (int i = index; i < events.Count; ++i)
                {
                    if (events[i - 1].End.Local < events[i].Start.Local)
                    {
                        freeTimeList.addFreeTimeBlockToList(new FreeTimeBlock((id++).ToString(),
                                                          events[i - 1].End.Local,
                                                          events[i].Start.Local)
                                      );
                    }

                }

                freeTimeList.addFreeTimeBlockToList(new FreeTimeBlock((id++).ToString(),
                                                  events[events.Count - 1].End.Local,
                                                  events[events.Count - 1].End.Local.AddDays(365))
                                      );
            }

            // xử lý lại list freeTimeList cho hợp lệ vì đã bị chỉnh sửa do time allowances
            for (int i = 0; i < freeTimeList.FreeTimeBlockList.Count - 1; i++)
            {
                if (freeTimeList.FreeTimeBlockList[i].StartDateTime >= freeTimeList.FreeTimeBlockList[i].EndDateTime)
                {
                    freeTimeList.FreeTimeBlockList.RemoveAt(i);
                    i--;
                }
            }
            ///////////////////////////////

            return freeTimeList;
        }

        //Chuyển thông tin một recurrence Appointment dạng daily thành list các events
        static List<Event> DailyRecurrence(Microsoft.Office.Interop.Outlook._AppointmentItem ApptItem)
        {
            List<Event> events = new List<Event>();
            iCalendar iCal = new iCalendar();
            Event evt = iCal.Create<Event>();
            evt.Start = ApptItem.Start;
            evt.End = ApptItem.End;
            events.Add(evt);
            int NumOfApps;
            if (ApptItem.GetRecurrencePattern().NoEndDate) NumOfApps = 100;
            else NumOfApps = ApptItem.GetRecurrencePattern().Occurrences;
            //if (!ApptItem.GetRecurrencePattern().NoEndDate)
            //{
                for (int i = 1; i < NumOfApps; i++)
                {
                    Event evt2 = iCal.Create<Event>();
                    evt2.Start = ApptItem.Start;
                    evt2.End = ApptItem.End;
                    evt2.Start = evt2.Start.AddDays(i * ApptItem.GetRecurrencePattern().Interval);
                    evt2.End = evt2.End.AddDays(i * ApptItem.GetRecurrencePattern().Interval);
                    events.Add(evt2);
                }
            //}
            return events;
        }

        //Chuyển thông tin một recurrence Appointment dạng monthly thành list các events
        static List<Event> MonthlyRecurrence(Microsoft.Office.Interop.Outlook._AppointmentItem ApptItem)
        {
            List<Event> events = new List<Event>();
            iCalendar iCal = new iCalendar();
            Event evt = iCal.Create<Event>();
            evt.Start = ApptItem.Start;
            evt.End = ApptItem.End;
            events.Add(evt);
            if (!ApptItem.GetRecurrencePattern().NoEndDate)
            {
                for (int i = 1; i < ApptItem.GetRecurrencePattern().Occurrences; i++)
                {
                    Event evt2 = iCal.Create<Event>();
                    evt2.Start = ApptItem.Start;
                    evt2.End = ApptItem.End;
                    evt2.Start = evt2.Start.AddMonths(i * ApptItem.GetRecurrencePattern().Interval);
                    evt2.End = evt2.End.AddMonths(i * ApptItem.GetRecurrencePattern().Interval);
                    events.Add(evt2);
                }
            }
            else
            {
                for (int i = 1; i < 12/*1 nam*/; i++)
                {
                    Event evt2 = iCal.Create<Event>();
                    evt2.Start = ApptItem.Start;
                    evt2.End = ApptItem.End;
                    evt2.Start = evt2.Start.AddMonths(i * ApptItem.GetRecurrencePattern().Interval);
                    evt2.End = evt2.End.AddMonths(i * ApptItem.GetRecurrencePattern().Interval);
                    events.Add(evt2);
                }
            }
            return events;
        }

        //Chuyển thông tin một recurrence Appointment dạng weekly thành list các events
        static List<Event> WeeklyRecurrence(Microsoft.Office.Interop.Outlook._AppointmentItem ApptItem)
        {
            List<Event> events = new List<Event>();
            int dayNum = Convert.ToInt16(ApptItem.GetRecurrencePattern().DayOfWeekMask);
            //Mảng daycheck được xây dựng với cấu trúc như sau
            //phần tử mang index từ 1-7 tương ứng từ chủ nhật tới thứ bảy
            //phần tử mang index từ 8-14 tương ứng từ chủ nhật tới thứ bảy, và lặp lại...
            //giá trị 1 thể hiện ngày đó thuộc recurrence này :D, và giá trị 0 là ngược lại
            Int16[] daycheck = new Int16[1000];

            //Tính số ngày trong một tuần của recurrence , biến NUmberOfDay
            int NumberOfDay = 0;
            if (dayNum >= 64) { NumberOfDay++; dayNum = dayNum - 64; }
            if (dayNum >= 32) { NumberOfDay++; dayNum = dayNum - 32; }
            if (dayNum >= 16) { NumberOfDay++; dayNum = dayNum - 16; }
            if (dayNum >= 8) { NumberOfDay++; dayNum = dayNum - 8; }
            if (dayNum >= 4) { NumberOfDay++; dayNum = dayNum - 4; }
            if (dayNum >= 2) { NumberOfDay++; dayNum = dayNum - 2; }
            if (dayNum >= 1) { NumberOfDay++; dayNum = dayNum - 1; }

            int NumberOfNodes;
            if (ApptItem.GetRecurrencePattern().NoEndDate) NumberOfNodes = 999;
            else NumberOfNodes = ((ApptItem.GetRecurrencePattern().Occurrences / NumberOfDay) + 1) * 7;

            //đánh dấu các ngày của recurrence này
            dayNum = Convert.ToInt16(ApptItem.GetRecurrencePattern().DayOfWeekMask);
            for (int i = 0; i < 100; i++) daycheck[i] = 0;
            // thứ bảy
            if (dayNum >= 64)
            {
                int j = 0;
                for (int i = 0; i <= NumberOfNodes; i++)
                    if (i - j * 7 == 7) { daycheck[i] = 1; j++; }
                dayNum = dayNum - 64;
            }
            //thứ sáu
            if (dayNum >= 32)
            {
                int j = 0;
                for (int i = 0; i <= NumberOfNodes; i++)
                    if (i - j * 7 == 6) { daycheck[i] = 1; j++; }
                dayNum = dayNum - 32;
            }
            //thứ năm
            if (dayNum >= 16)
            {
                int j = 0;
                for (int i = 0; i <= NumberOfNodes; i++)
                    if (i - j * 7 == 5) { daycheck[i] = 1; j++; }
                dayNum = dayNum - 16;
            }
            //thứ tư
            if (dayNum >= 8)
            {
                int j = 0;
                for (int i = 0; i <= NumberOfNodes; i++)
                    if (i - j * 7 == 4) { daycheck[i] = 1; j++; }
                dayNum = dayNum - 8;
            }
            //thứ ba
            if (dayNum >= 4)
            {
                int j = 0;
                for (int i = 0; i <= NumberOfNodes; i++)
                    if (i - j * 7 == 3) { daycheck[i] = 1; j++; }
                dayNum = dayNum - 4;
            }
            //thứ hai
            if (dayNum >= 2)
            {
                int j = 0;
                for (int i = 0; i <= NumberOfNodes; i++)
                    if (i - j * 7 == 2) { daycheck[i] = 1; j++; }
                dayNum = dayNum - 2;
            }
            //chủ nhật
            if (dayNum >= 1)
            {
                int j = 0;
                for (int i = 0; i <= NumberOfNodes; i++)
                    if (i - j * 7 == 1) { daycheck[i] = 1; j++; }
                dayNum = dayNum - 1;
            }

            //Kiểm tra ngày bắt đầu của recurrence là thứ mấy trong tuần, chủ nhật tương ứng với phần tử có index = 1 trong mảng daycheck
            int CheckPointer = 0;
            switch (Convert.ToInt16(ApptItem.Start.DayOfWeek))
            {
                case 0://chủ nhật
                    CheckPointer = 1;
                    break;
                case 1://thứ hai
                    CheckPointer = 2;
                    break;
                case 2://thứ ba
                    CheckPointer = 3;
                    break;
                case 3://thứ tư
                    CheckPointer = 4;
                    break;
                case 4://thư năm
                    CheckPointer = 5;
                    break;
                case 5://thứ sáu
                    CheckPointer = 6;
                    break;
                case 6://thứ bảy
                    CheckPointer = 7;
                    break;
            }


            iCalendar iCal = new iCalendar();
            Event evt = iCal.Create<Event>();
            evt.Start = ApptItem.Start;
            evt.End = ApptItem.End;
            events.Add(evt);

            // tạo các appointment và add vào list các events 
            DateTime StartTime = new DateTime();
            StartTime = evt.Start.Local;
            DateTime EndTime = new DateTime();
            EndTime = evt.End.Local;
            int NumberOfApps;
            if (ApptItem.GetRecurrencePattern().NoEndDate) NumberOfApps = 365;
            else NumberOfApps = ApptItem.GetRecurrencePattern().Occurrences;
            int old = CheckPointer;
            int count = 1;
            do
            {
                CheckPointer++;
                if (daycheck[CheckPointer] == 1)
                {
                    int spanTime = CheckPointer - old;
                    Event evts = iCal.Create<Event>();
                    evts.Start = StartTime.AddDays(spanTime);
                    evts.End = EndTime.AddDays(spanTime);
                    events.Add(evts);
                    StartTime = evts.Start.Local;
                    EndTime = evts.End.Local;
                    old = CheckPointer;
                    count++;
                }
            }
            while ((count < NumberOfApps) && (CheckPointer < NumberOfNodes));

            return events;
        }

        //GHi list các events vào outlook
        public void WriteEventToOutlook(List<Event> events)
        {

            //OutLook._Application outlookObj = new OutLook.Application();
            // OutLook.MAPIFolder fldCal = (OutLook.MAPIFolder)outlookObj.Session.GetDefaultFolder(OutLook.OlDefaultFolders.olFolderCalendar);
            for (int i = 0; i < events.Count; i++)
            {
                OutLook._AppointmentItem newApp = (OutLook._AppointmentItem)OUTLOOK_FOLDER_CAL.Items.Add(OutLook.OlItemType.olAppointmentItem);
                newApp.Subject = events[i].Summary;
                newApp.Start = events[i].Start.Value;
              
                newApp.End = events[i].End.Value;
              
                newApp.Categories = "JSKE";
                newApp.Save();
            }
        }

        //Xóa các appointment do chương trình JSKE ghi vào outlook
        void RollBack()
        {
            //OutLook._Application outlookObj = new OutLook.Application();
            //OutLook.MAPIFolder fldCal = (OutLook.MAPIFolder)outlookObj.Session.GetDefaultFolder(OutLook.OlDefaultFolders.olFolderCalendar);


            List<Microsoft.Office.Interop.Outlook._AppointmentItem> Apps = new List<OutLook._AppointmentItem>();
            foreach (Microsoft.Office.Interop.Outlook._AppointmentItem ApptItem in OUTLOOK_FOLDER_CAL.Items)
            {
                Apps.Add(ApptItem);
            }
            for (int j = 0; j < Apps.Count; j++)
            {
                if (Apps[j].Categories == "JSKE") Apps[j].Delete();
            }
        }

        #endregion

        private List<Appointment> ConvertEventToAppointment(List<Event> events)
        {
            List<Appointment> appointments = new List<Appointment>();
            foreach (Event e in events)
            {
                Appointment appointment = new Appointment();
                appointment.StartDate = e.Start.Local;
                appointment.EndDate = e.End.Local;
                appointment.Title = e.Summary;
                appointments.Add(appointment);
            }
            return appointments;
        }

        public List<Event> GetListEvents()
        {
            return eventsResult;
        }
        
        void scheduleThread()
        {
            //bFinish = false;
            //Goi ham de chuyen freetimeList
            string name = OUTLOOK_FOLDER_CAL.FolderPath;
            presenter.SendFreeTimeListToEngine(FreeTimeListFromOutlook());
            //goi ham schedule tao list event
            updateProgressBar(28);
            eventsResult = presenter.ScheduleCalendar(progressBar1);
            progressBar1.Value = 100;
            if (eventsResult != null)
            {
                List<Appointment> appointments = ConvertEventToAppointment(eventsResult);
                CalendarForm newCalForm = new CalendarForm(this);
                newCalForm.Appointments = appointments;
                newCalForm.ShowDialog();                
            }
            else
            {
                MessageBox.Show("There are no Results to Display!\nPlease input the appropriate Tasks and WorkingHours", "Important Note", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void btnViewReport_Click(object sender, EventArgs e)
        {
            ScheduleReportForm srf = new ScheduleReportForm();            
        }

        private void CellContentDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                if (_bindingSource.Count != 0)
                {
                    Form taskdlg = new TaskForm((Task)_bindingSource[e.RowIndex]);
                    taskdlg.ShowDialog(this);
                }
                else
                {
                    MessageBox.Show("There are no Task to display", 
                        "Important Note", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            catch
            {
                MessageBox.Show("You clicked on the wrong place",
                    "Important Note", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void btnRollBackCalendar_Click(object sender, EventArgs e)
        {
            RollBack();
        }

        private void btnViewDiary_Click(object sender, EventArgs e)
        {
            DiaryForm diaryForm = new DiaryForm();
            diaryForm.ShowDialog(this);
        }

        private void btnDiaryAnalyzer_Click(object sender, EventArgs e)
        {
            DiaryAnalyzeForm diaryAnalyzeForm = new DiaryAnalyzeForm();
            diaryAnalyzeForm.ShowDialog(this);
        }

        private void btnUpdateTaskProg_Click(object sender, EventArgs e)
        {
            TrackingTask trackTaskForm = new TrackingTask();
            trackTaskForm.ShowDialog(this);
            refreshTaskListData();
        }

        private void btnViewTaskRept_Click(object sender, EventArgs e)
        {
            TaskReport taskReportForm = new TaskReport();
            taskReportForm.ShowDialog(this);
        }

        private void BindListViewTask(List<Task> taskList, SystemConfiguration sysConf)
        {
            listViewTask.SuspendLayout();
            listViewTask.Items.Clear();
            String[] status = new String[] {"Not Started", "In Progress", "Completed", "Waiting on someone else", "Deferred" };
            String deadline = "";
            String schedStart = "";
            String schedEnd = "";
            foreach (Task t in taskList)
            {
                if (t.DueDate > DateTime.Now.AddYears(-30) && t.DueDate < DateTime.Now.AddYears(30))
                {
                    deadline = Convert.ToString(t.DueDate);
                }
                else
                {
                    deadline = "";
                }
                if (t.ScheduledStartDate.Year > DateTime.Now.AddYears(-30).Year && t.ScheduledStartDate.Year < DateTime.Now.AddYears(30).Year)
                {
                    schedStart = Convert.ToString(t.ScheduledStartDate);
                }
                else
                {
                    schedStart = "";
                }
                if (t.ScheduledEndDate > DateTime.Now.AddYears(-30) && t.ScheduledEndDate < DateTime.Now.AddYears(30))
                {
                    schedEnd = Convert.ToString(t.ScheduledEndDate);
                }
                else
                {
                    schedEnd = "";
                }
                
                ListViewItem item = new ListViewItem(new String[] {
                    Convert.ToString(t.TaskID),
                    t.Name,
                    Convert.ToString(t.Priority),
                    Convert.ToString(t.RemainTime),
                    deadline,
                    sysConf.TabWorkingHoursData.ListOfWorkingHourItems[t.WorkingHourID].WorkingHourName,
                    sysConf.TabProjectData.ListProjectName[t.ProjectID],
                    status[t.TaskStatusIndex],
                    schedStart,
                    schedEnd
                });
                if (t.ScheduledEndDate > t.DueDate)
                {
                    item.BackColor = Color.Yellow;
                }
                listViewTask.Items.Add(item);
            }
            if (this.currSelectedIndex > -1)
            {
                listViewTask.Items[this.currSelectedIndex].Selected = true;
            }
            listViewTask.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            listViewTask.ResumeLayout();
        }

        private void listViewTask_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (taskList != null && sysConfig != null)
            {
                if (listViewTask.Items.Count > 0)
                {
                    if (listViewTask.SelectedItems.Count > 0)
                    {
                        this.currSelectedIndex = listViewTask.SelectedIndices[0];
                        currTask = taskList[listViewTask.SelectedIndices[0]];
                        txtTaskName.Text = currTask.Name;
                        cbbPriority.SelectedItem = Convert.ToString(currTask.Priority);
                        txtRemain.Text = Convert.ToString(currTask.RemainTime);
                        if (!currTask.DueDate.Equals(DateTime.MaxValue))
                        {
                            cbbExternalConstraint.SelectedItem = PresenterMainForm.ExternalConstraints.FINISH_ON_OR_BEFORE;
                            dtpkDeadline.Enabled = true;
                            dtpkDeadline.Value = currTask.DueDate;
                        }
                        else
                        {
                            cbbExternalConstraint.SelectedItem = PresenterMainForm.ExternalConstraints.NO_CONSTRAINT;
                            dtpkDeadline.Enabled = false;
                        }
                        cbbWHName.SelectedIndex = currTask.WorkingHourID;
                        cbbProjectName.SelectedIndex = currTask.ProjectID;
                        cbbTaskStatus.SelectedIndex = currTask.TaskStatusIndex;
                        btnUpdate.Enabled = true;
                        btnCancelUpdate.Enabled = true;
                        btnInsert.Enabled = false;
                    }
                    else
                    {
                        cbbExternalConstraint.SelectedIndex = 0;
                        cbbPriority.SelectedIndex = 0;
                        cbbProjectName.SelectedIndex = 0;
                        cbbWHName.SelectedIndex = 0;
                        cbbTaskStatus.SelectedIndex = 1;
                        txtTaskName.Text = "Type new Task Name";
                        txtRemain.Text = "30";
                        btnInsert.Enabled = true;
                        btnCancelUpdate.Enabled = false;
                        btnUpdate.Enabled = false;
                    }
                }
            }
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (txtTaskName.Text.Trim() != "")
                currTask.Name = txtTaskName.Text;
            currTask.Priority = int.Parse(cbbPriority.SelectedItem.ToString());
            currTask.RemainTime = int.Parse(txtRemain.Text);
            if (cbbExternalConstraint.SelectedIndex == 1)
            {
                currTask.DueDate = dtpkDeadline.Value;
            }
            else if (cbbExternalConstraint.SelectedIndex == 0)
            {
                currTask.DueDate = DateTime.MaxValue;
            }
            currTask.WorkingHourID = cbbWHName.SelectedIndex;
            currTask.ProjectID = cbbProjectName.SelectedIndex;
            currTask.TaskStatusIndex = cbbTaskStatus.SelectedIndex;
            presenter.updateTask2File(currTask);

            refreshTaskListData();
            btnUpdate.Enabled = false;
            btnCancelUpdate.Enabled = false;
            btnInsert.Enabled = true;
        }

        private void btnCancelUpdate_Click(object sender, EventArgs e)
        {
            listViewTask.SelectedItems.Clear();
            //listViewTask.ResumeLayout();
            btnUpdate.Enabled = false;
            btnCancelUpdate.Enabled = false;
            btnInsert.Enabled = true;
        }

        private void listTaskView_DoubleClick(object sender, EventArgs e)
        {
            if (listViewTask.SelectedItems.Count > 0)
            {
                TaskForm tf = new TaskForm(taskList[listViewTask.SelectedIndices[0]]);
                tf.ShowDialog(this);
                refreshTaskListData();
            }
        }
        Boolean sortedSatisfy = true;
        private void listTaskView_ColumClick(object sender, ColumnClickEventArgs e)
        {
            btnInsert.Enabled = true;
            btnUpdate.Enabled = false;
            btnCancelUpdate.Enabled = false;
            int col = e.Column;
            if(col == 0)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.TaskID.CompareTo(t2.TaskID);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.TaskID.CompareTo(t1.TaskID);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
            else if( col == 1)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.Name.CompareTo(t2.Name);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.Name.CompareTo(t1.Name);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
            else if (col == 2)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.Priority.CompareTo(t2.Priority);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.Priority.CompareTo(t1.Priority);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
            else if (col == 3)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.RemainTime.CompareTo(t2.RemainTime);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.RemainTime.CompareTo(t1.RemainTime);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
            else if (col == 4)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.DueDate.CompareTo(t2.DueDate);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.DueDate.CompareTo(t1.DueDate);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
            else if (col == 5)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.WorkingHourID.CompareTo(t2.WorkingHourID);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.WorkingHourID.CompareTo(t1.WorkingHourID);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
            else if (col == 6)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.ProjectID.CompareTo(t2.ProjectID);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.ProjectID.CompareTo(t1.ProjectID);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
            else if (col == 7)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.TaskStatusIndex.CompareTo(t2.TaskStatusIndex);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.TaskStatusIndex.CompareTo(t1.TaskStatusIndex);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
            else if (col == 8)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.ScheduledStartDate.CompareTo(t2.ScheduledStartDate);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.ScheduledStartDate.CompareTo(t1.ScheduledStartDate);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
            else if (col == 9)
            {
                if (sortedSatisfy)
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t1.ScheduledEndDate.CompareTo(t2.ScheduledEndDate);
                    });
                    sortedSatisfy = false;
                    BindListViewTask(taskList, sysConfig);
                }
                else
                {
                    taskList.Sort(delegate(Task t1, Task t2)
                    {
                        return t2.ScheduledEndDate.CompareTo(t1.ScheduledEndDate);
                    });
                    sortedSatisfy = true;
                    BindListViewTask(taskList, sysConfig);
                }
            }
        }

        private void btnInsert_Click(object sender, EventArgs e)
        {
            Task newTask = new Task();
            if (txtTaskName.Text.Trim() != "")
                newTask.Name = txtTaskName.Text;
            newTask.Priority = int.Parse(cbbPriority.SelectedItem.ToString());
            newTask.RemainTime = int.Parse(txtRemain.Text);
            if (cbbExternalConstraint.SelectedIndex == 1)
            {
                newTask.DueDate = dtpkDeadline.Value;
            }
            else if (cbbExternalConstraint.SelectedIndex == 0)
            {
                newTask.DueDate = DateTime.MaxValue;
            }
            newTask.WorkingHourID = cbbWHName.SelectedIndex;
            newTask.ProjectID = cbbProjectName.SelectedIndex;
            newTask.TaskStatusIndex = cbbTaskStatus.SelectedIndex;
            presenter.addNewTask2File(newTask);

            refreshTaskListData();
            btnUpdate.Enabled = false;
            btnCancelUpdate.Enabled = false;
            btnInsert.Enabled = true;
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            refreshTaskListData();
        }
        bool flagLangFirstLoad = true;
        private int currSelectedIndex = -1;

        private void cbLang_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (flagLangFirstLoad)
            {
                flagLangFirstLoad = false;
                return;
            }
            Properties.Settings.Default.Language = cbLang.SelectedItem.ToString();
            Properties.Settings.Default.Save();
            SetLanguage();
        }
        public void GetLangAvailable()
        {
            DirectoryInfo dir = new DirectoryInfo("Lang");
            foreach (FileInfo f in dir.GetFiles("*.xml"))
            {
                string lang = f.Name.Substring(0, f.Name.Length - 4);
                cbLang.Items.Add(lang);
            }
            cbLang.Text = Properties.Settings.Default.Language;

        }

        private void btnAbout_Click(object sender, EventArgs e)
        {
            FrmAbout f = new FrmAbout();
            f.ShowDialog();
        }

        private void btnViewCalendar_Click(object sender, EventArgs e)
        {
            CalendarForm f = new CalendarForm(CalendarForm.SHOW_SCHED_CALENDAR, this);
            f.ShowDialog(this);
        }

        private void cbbWHName_SelectedIndexChanged(object sender, EventArgs e)
        {
            
        }

        private void cbbExternalConstraint_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbbExternalConstraint.SelectedIndex == 0)
            {
                dtpkDeadline.Enabled = false;
            }
            else
            {
                dtpkDeadline.Enabled = true;
            }
        }

        private void btnInputTaskUsingNLP_Click(object sender, EventArgs e)
        {
            NLPTaskForm nlpTaskForm = new NLPTaskForm();
            this.Hide();
            nlpTaskForm.ShowDialog(this);
            this.Show();
        }
    }
}
